//////////////////////////////////////////////
// System.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkAstraeus
{
	class ComplexEffectManager ;
	class ContentLoader ;
	class EffectManager ;
	class EnvironmentRenderer ;
	class GraphicsEngine ;
	class LogManager ;
	class MaterialManager ;
	class PbsEnvironmentMapFilter ;
	class ProjectLoader ;
	class ScriptsEngine ;
}

/// Includes ---------------------------------

// nkAstraeus
#include "Dll/DllDefines.h"

#include "Configurations/Configuration.h"

// nkCommon
#include <nilkinsCommon/Patterns/MaybeSingletonClass.h>

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

/// Class ------------------------------------

namespace nkAstraeus
{
	class DLL_ASTRAEUS_EXPORT System final : public nkCommon::MaybeSingletonClass<System>
	{
		public :

			// Constructor, destructor
			System () noexcept ;
			virtual ~System () ;

			// Getters
			GraphicsEngine* getGraphicsEngine () const ;
			ScriptsEngine* getScriptsEngine () const ;
			ContentLoader* getContentLoader () const ;
			ProjectLoader* getProjectLoader () const ;
			PbsEnvironmentMapFilter* getPbsEnvironmentMapFilter () const ;
			EnvironmentRenderer* getEnvironmentRenderer () const ;
			ComplexEffectManager* getComplexEffectManager () const ;
			EffectManager* getEffectManager () const ;
			LogManager* getLogManager () const ;
			MaterialManager* getMaterialManager () const ;

			// Lifetime
			bool initialize (const Configuration& config = Configuration()) ;
			void shutdown () ;

		private :

			// Constructor
			System (bool isSingleton) noexcept ;
			System (const System&) = delete ;
			System (System&&) = delete ;

			// Operators
			System& operator= (const System&) = delete ;
			System& operator= (System&&) = delete ;

		private :

			// Attributes
			// Engines
			nkMemory::UniquePtr<GraphicsEngine> _graphicsEngine ;
			nkMemory::UniquePtr<ScriptsEngine> _scriptsEngine ;

			// Loaders
			nkMemory::UniquePtr<ContentLoader> _contentLoader ;
			nkMemory::UniquePtr<ProjectLoader> _projectLoader ;

			// Utils
			nkMemory::UniquePtr<PbsEnvironmentMapFilter> _pbsEnvironmentMapFilter ;
			nkMemory::UniquePtr<EnvironmentRenderer> _environmentRenderer ;

			// Managers
			ComplexEffectManager* _complexEffectManager ;
			EffectManager* _effectManager ;
			LogManager* _logManager ;
			MaterialManager* _materialManager ;

		private :

			friend class nkCommon::MaybeSingletonClass<System> ;
	} ;
}